/*
 * MonomialIdealDecompose.java
 *
 * Created on February 22, 2005, 1:51 PM
 */

package com.milowski.monos.component;


import com.milowski.monos.*;
import com.milowski.monos.tools.Shell;
import org.infoset.component.Component;
import org.infoset.component.ItemFilterComponent;
import org.infoset.xml.Document;
import org.infoset.xml.Element;
import org.infoset.xml.InfosetFactory;
import org.infoset.xml.ItemConstructor;
import org.infoset.xml.ItemDestination;
import org.infoset.xml.Name;
import org.infoset.xml.XMLException;
import org.infoset.xml.filter.SubtreeFilter;

/**
 *
 * @author R. Alexander Milowski
 */
public class EvalComponent extends MonosComponentBase
{
   
   static Name componentName = InfosetFactory.createName(XML.STEPS_NAMESPACE,"eval");
   static Name [] subtreeNames = { XML.expressionName };
   static {
      try {
         Shell.init();
      } catch (Exception ex) {
         ex.printStackTrace();
      }
   }
   
   public static class ComponentFilter extends SubtreeFilter {
      
      ComponentFilter() {
         super(subtreeNames);
      }
      public void process(Document doc) 
         throws XMLException
      {
         Element top = doc.getDocumentElement();
         String outputValue = top.getAttributeValue("output");
         boolean mathmlOutput = outputValue!=null && outputValue.equals("mathml");

         String value = top.getText();
         try {
            Object sobj;
            try {
               sobj = Shell.eval(value);
            } catch (Throwable ex) {
               XML.error(output,"Error in evaluating expression: "+ex.getMessage());
               return;
            }
            output(mathmlOutput,sobj);
         } catch (Exception ex) {
            throw new XMLException("Parse exception: "+ex.getMessage());
         }
      }
      
      protected void output(boolean asMathML,Object sobj) 
         throws XMLException
      {
         ItemConstructor constructor = InfosetFactory.getDefaultInfoset().createItemConstructor();
         if (asMathML) {
            throw new XMLException("Mathml format not supported.");
         } else {
            post(constructor.createElement(XML.expressionName));
            post(constructor.createCharacters(sobj.toString()));
            post(constructor.createElementEnd(XML.expressionName));
         }
      }
      
   }
   
   /** Creates a new instance of KernelBasisComponent */
   public EvalComponent()
   {
      super(componentName);
   }
   
   public Component newInstance() 
      throws XMLException
   {
      final ComponentFilter filter = new ComponentFilter();
      return new ItemFilterComponent(name,vendor,version,filter,inputPortName,outputPortName);
   }
   
   
}
